//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_CONSOLE_H__
#define __ELASTOS_CONSOLE_H__

#define SCANCODE(key)  (key | 128)
#define ASCIICODE(key) (key)

#define KEY_TAB ASCIICODE('\t')
#define KEY_NL ASCIICODE('\n')
#define KEY_CR ASCIICODE('\r')
#define KEY_ENTER ASCIICODE('\r')
#define KEY_BS ASCIICODE('\b')
#define KEY_ESC ASCIICODE(27)
#define KEY_CTL_C ASCIICODE(3)

#define SOLIDCURSOR            1
#define NORMALCURSOR           0
#define HISTORY_NUMBER         8
#define HISTORY_MAX_LENGTH     512

enum {
    ASCII_LeftArrow =  0xE0,
    ASCII_RightArrow = 0xE1,
    ASCII_Insert =     0xE2,
    ASCII_Delete =     0xE3,
    ASCII_Home =       0xE4,
    ASCII_End =        0xE5,
    ASCII_UpArrow =    0xE6,
    ASCII_DownArrow =  0xE7,
    ASCII_PageUp =     0xE8,
    ASCII_PageDown =   0xE9,
    ASCII_At =         0xEA,
    ASCII_Tab =        0x09,
    ASCII_BackSpace =  0x08,
    ASCII_SPACE =      0x20,
    ASCII_ENTER =      0x0D,
    ASCII_F1 =         0xBB,
    ASCII_F2 =         0xBC,
    ASCII_F3 =         0xBD,
    ASCII_F4 =         0xBE,
    ASCII_F5 =         0xBF,
    ASCII_F6 =         0xC0,
    ASCII_F7 =         0xC1,
    ASCII_F8 =         0xC2,
    ASCII_F9 =         0xC3,
    ASCII_F10 =        0xC4,
    ASCII_F11 =        0xD7,
    ASCII_F12 =        0xD8,
};

class Console : public CDeviceDriver
{
private:
    CARAPI VTermRead(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);


public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf * pBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ const MemoryBuf & buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ const MemoryBuf & inBuffer,
        /* [out] */ MemoryBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI WriteToScreen(
           /* [in] */ Int64 u64Offset,
           /* [in] */ const MemoryBuf & buffer,
           /* [out] */ Int32 * pBytesWritten,
           /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose() {}

    ECode Initialize();

    void MoveCursorForward(UInt32 c);

    void SetCursorType(int cursortype);

    int TranslateAscii(int ch);

    ~Console()
    {
        if (NULL != m_pOldPrint) {
            _print = m_pOldPrint;
        }

        for (int i = 0; i < HISTORY_NUMBER; i++) {
            if (*m_ppHistory[i]) free(m_ppHistory[i]);
        }
    }

public:
    Boolean            m_bBuffer;
    int             m_TempValue;
    int             m_FirstRecord;
    int             m_CurrentRecord;
    IDeviceDriver         *m_pConsoleDevDriver;
    char            *m_ppHistory[HISTORY_NUMBER];
    void            (CDECL *m_pOldPrint)(const char *);
};

#endif // __ELASTOS_CONSOLE_H__
